﻿using Common.Class;
using Models;
using System.Diagnostics;
using System.Text;

namespace JLMiddlewares
{
    /// <summary>
    /// 请求日志中间件
    /// </summary>
    public class RequestLogMiddleware
    {
        private readonly RequestDelegate _next;

        public RequestLogMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {

            StringBuilder _sb = new StringBuilder();

            context.Request.EnableBuffering();
            StreamReader requestReader = new StreamReader(context.Request.Body);
            string requestContent = string.Empty;
            requestContent = await requestReader.ReadToEndAsync();

            context.Request.Body.Position = 0;

            Stopwatch _sw = Stopwatch.StartNew();

            var originalResponseStream = context.Response.Body;

            using (var ms = new MemoryStream())
            {
                if (context.Response.StatusCode != StatusCodes.Status500InternalServerError)
                {
                    context.Response.Body = ms;
                }

                await _next(context).ConfigureAwait(false);

                _sw.Stop();

                string responseContent = string.Empty;
                if (context.Response.StatusCode != StatusCodes.Status500InternalServerError)
                {
                    ms.Position = 0;
                    StreamReader responseReader = new StreamReader(ms);
                    responseContent = responseReader.ReadToEnd();
                    ms.Position = 0;
                    await ms.CopyToAsync(originalResponseStream);
                    context.Response.Body = originalResponseStream;
                }


                string _tokenID = string.Empty;
                if (context.Request.Headers.ContainsKey("TokenID") && !string.IsNullOrWhiteSpace(context.Request.Headers["TokenID"].ToString()))
                {
                    _tokenID = context.Request.Headers["TokenID"];

                }

#if DEBUG
                _sb.AppendLine(DateTime.Now.ToString("HH:mm:ss.fff"));
                _sb.AppendLine(string.Format("请求结束 {0},耗时 {1} ms, 状态码: {2}, IP {3} ,TokenID {4}", context.Request.Path, _sw.ElapsedMilliseconds, context.Response.StatusCode, context.Connection.RemoteIpAddress.MapToIPv4().ToString() + ":" + context.Connection.RemotePort, _tokenID));

                if (!string.IsNullOrWhiteSpace(requestContent))
                {
                    //如果请求主题内容不为空，则输出请求内容
                    _sb.AppendLine($"Request Body: {System.Web.HttpUtility.UrlDecode(requestContent)}");
                }

                if (context.Request.Path.ToString().IndexOf(".") == -1)
                {
                    //如果返回的不是静态页，则输出请求返回内容
                    _sb.AppendLine($"Response Body: " + responseContent);
                }


                Console.WriteLine("----------------------------------------------------------------------------------------------------------------");
                Console.WriteLine(_sb.ToString());

#endif


                //记录访问日志
                RequestLogModel _requestLog = new RequestLogModel();
                _requestLog.ID = CommonHelper.GetNewID(1);
                _requestLog.URL = context.Request.Path;
                if (context.Request.Path.ToString().IndexOf(".") == -1)
                {
                    _requestLog.RequestBody = System.Web.HttpUtility.UrlDecode(requestContent);
                }
                _requestLog.CreateTime = DateTime.Now;
                _requestLog.ClientIP = context.Connection.RemoteIpAddress.MapToIPv4().ToString() + ":" + context.Connection.RemotePort;
                _requestLog.StateCode = context.Response.StatusCode;
                _requestLog.UseTime = _sw.ElapsedMilliseconds;
                _requestLog.TokenID = _tokenID;
                _requestLog.ResponseBody = responseContent;


                LogHelper.WriteLogToFile("Request", JsonHelper.GetJsonStrFromObject(_requestLog), "");

            }


        }
    }
}
